package com.foodlocker.machine;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.dwin.navy.serialportapi.SerailPortOpt;
import com.foodlocker.common.CommonFunction;

public class Box {

	
	public SerailPortOpt  serialPortOpt;
	public InputStream mInputStream;	
	 private static final String CHILD_TAG = "PCBChildThread";
	 Handler mMainHandler;
	public PCBChildThread mPCBChildThread;
	public static byte[][] staticlocksState= new byte[7][9];  //0不用，1-5控制箱格，6控制加热器。
	public static int FirstHeatertoBoxID=40;  //为了调试方便，把加热器对应的继电器地址重新赋值到1，之后要改为41，
	public static int HeaterTaskRunCount=0;
	Timer heaterTimer;
	 public static  Handler childHander = null;
	public Box(Handler mainHandler) {
		super();
		this.mMainHandler=mainHandler;
		// TODO Auto-generated constructor stub
		
		 initSerialPort();
		mPCBChildThread= new PCBChildThread();
		mPCBChildThread.start();
	}
	@Override
	protected void finalize() throws Throwable {
		// TODO Auto-generated method stub
		super.finalize();		
	    Log.i(CHILD_TAG, "Stop looping the child thread's message queue");

        if ( childHander != null) {
        	childHander.getLooper().quit();
				        }
			
	}
	
	public class PCBChildThread extends Thread {
       
        public PCBChildThread() {
			super();
			// TODO Auto-generated constructor stub
		}
		public void run() {
            this.setName("PCBChildThread");

            // 初始化消息循环队列，需要在Handler创建之前
            Looper.prepare();

            childHander = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    String checkRelayString="";
                    Log.i(CHILD_TAG,
                            "Got an incoming message from the main thread - what is: "+msg.what
                             +"obj is:"       + msg.obj);
                    
                  if(msg.what==1){
                	  List<Integer> boxes=(List<Integer>) msg.obj;
                	  for(int i=0;i<boxes.size();i++){               		  
                	  int boxID= boxes.get(i)-1; //叫法上的1号对应这里的0号，所以要减1
                      byte PCBID= (byte)(boxID/8+1); //从1开始
          			 byte RelayID=(byte)(boxID%8);
          			 boolean isRelayOpen,isDoorOpen;
          			 
                	if(staticlocksState[PCBID][RelayID]==(byte)0x01){ 
                		System.out.println("pcb="+PCBID+"relay="+RelayID+"is already open"); 
                		continue ;}	         		
                		    staticlocksState[PCBID][RelayID]=(byte)0x01; 
                		    byte[][] onBytes=CommonFunction.generateOpenRelayBytes(boxID,staticlocksState[PCBID]);
        					serialPortOpt.writeBytes(onBytes[0]);	
        					CloseRelayTask closeRelayTask= new CloseRelayTask(boxID);
        					Timer myTimer= new Timer();
        					myTimer.schedule(closeRelayTask, 600);
        					
        					//注意，这里一定要等待一会儿，让线路板执行完上一次命令，不然会读不出来继电器状态数据。
        					 myThreadSleep(200);
        					
        					serialPortOpt.writeBytes(onBytes[1]);//读取继电器输出状态
                             isRelayOpen=isOpen(PCBID,RelayID);  System.out.println("relay check open " +isRelayOpen);  if(!isRelayOpen ) { continue; }       										
        					serialPortOpt.writeBytes(onBytes[2]);	//读取线路板输入状态,注意，这里是关门 01，开门00
        					 isDoorOpen= !isOpen(PCBID,RelayID);  System.out.println("relay door open "+isDoorOpen); if(!isDoorOpen ) { continue; }
        					 myThreadSleep(300); // 这个时间用于控制两个相领开动作之间的时间，开得太快电源受不了
                	  }
                  } //end of msg.what==1 
                                    
                  if(msg.what==2)  {  int[] heatTime=(int[])msg.obj;
                	  
                 heaterControl(heatTime); 
                  } 
                  
                }

            };

            // 启动子线程消息循环队列
            Looper.loop();

        }
    }
	private void myThreadSleep (long howLong){
		try {
			Thread.sleep(howLong);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private boolean isOpen(byte PCBID, byte RelayID){
		byte[] buf= new byte[512];
		 byte[] state=null ;		
	     boolean is_open=false;	  
	     long times = 0;
	     
		while(true){
			   int size;
			   times++;
			   if(times>655000) {  
			    	break;    }
				if(mInputStream==null) { 	
					System.out.println("the ReadThread is returned bexcause  mInputStream is:"+mInputStream); 
					continue; }				 
			     size=serialPortOpt.readBytes(buf);
			    if(size>0) {		 
			    state = new byte[size];
				System.arraycopy(buf, 0, state, 0, size);					
		       String	checkString=bytesToHexString(state,state.length);
		    	//System.out.println(" the checkRelayString is:"+checkRelayString);
		    	 Log.i(CHILD_TAG," the box_door_state is:"+checkString);
		    	 if(state[RelayID+4]==(byte)0x01) { 
		    		 if (state[2]==PCBID ) is_open=true;}
			     break;
			    }
			   
			}
		return is_open;
	}  
	
	private void initSerialPort(){
		 
		 serialPortOpt= new SerailPortOpt();
		 serialPortOpt.mDevNum=0;
		 serialPortOpt.mDataBits=8;
		 serialPortOpt.mSpeed=115200;
		 serialPortOpt.mStopBits=1;
		 serialPortOpt.mParity='n';
		 serialPortOpt.openDev(serialPortOpt.mDevNum);
		 serialPortOpt.setSpeed(serialPortOpt.mFd, serialPortOpt.mSpeed);
		 serialPortOpt.setParity(serialPortOpt.mFd, serialPortOpt.mDataBits , serialPortOpt.mStopBits,  serialPortOpt.mParity);
		 mInputStream=serialPortOpt.getInputStream();
	}
	

	
	public static String bytesToHexString(byte[] src, int size) {
		String ret = "";
		if (src == null || size <= 0) {
			return null;
		}
		for (int i = 0; i < size; i++) {
			String hex = Integer.toHexString(src[i] & 0xFF);
			//Log.i(TAG, hex);
			if (hex.length() < 2) {
				hex = "0" + hex;
			}
			hex += " ";
			ret += hex;
		}
		return ret.toUpperCase();
	}
	
	
	
	class CloseRelayTask extends TimerTask{
        int  boxID;
        
		public CloseRelayTask(int boxID) {
			super();
			this.boxID = boxID;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			
			  byte PCBID= (byte)(boxID/8+1);
  			byte RelayID=(byte)(boxID%8);
  			staticlocksState[PCBID][RelayID]=(byte)0x00;
  			byte[][] onBytes=CommonFunction.generateOpenRelayBytes(boxID,staticlocksState[PCBID]);
  			serialPortOpt.writeBytes(onBytes[0]); 
			
		}
		
	}
	class HeaterControlTask extends TimerTask{
       
		int  boxID;
		int[] heatTimes; 
		 byte PCBID;
		public HeaterControlTask(int boxID,int[] heatTimes) {
			super();
			this.boxID = boxID;
			this.heatTimes=heatTimes;
			PCBID= (byte)(boxID/8+1);
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if(HeaterTaskRunCount==0) {
				 System.out.println("--------HeaterTaskRunCount="+HeaterTaskRunCount+"---------");
			if(heatTimes[HeaterTaskRunCount]>2)	staticlocksState[PCBID][HeaterTaskRunCount]=(byte)0x01;
				byte[][] onBytes=CommonFunction.generateOpenRelayBytes(boxID,staticlocksState[PCBID]);
	  			serialPortOpt.writeBytes(onBytes[0]);	
	  		//定义下一个加热时间
				heaterTimer.cancel();
			    heaterTimer= new Timer(); 
				heaterTimer.schedule(new HeaterControlTask(FirstHeatertoBoxID, heatTimes), heatTimes[HeaterTaskRunCount]*100);
				//执行步骤加一。
				 HeaterTaskRunCount++;
			} 
			else if(HeaterTaskRunCount>0&&HeaterTaskRunCount<5) {
				 System.out.println("--------HeaterTaskRunCount="+HeaterTaskRunCount+"---------");
  			// 上一个加热器关闭
  			staticlocksState[PCBID][HeaterTaskRunCount-1]=(byte)0x00;
  			//下一个加热器打开加热时间太短，就不加热，继电器受不了。
  			if(heatTimes[HeaterTaskRunCount]>2) staticlocksState[PCBID][HeaterTaskRunCount]=(byte)0x01;
  			byte[][] onBytes=CommonFunction.generateOpenRelayBytes(boxID,staticlocksState[PCBID]);
  			serialPortOpt.writeBytes(onBytes[0]);			
  			 //定义下一个加热时间
				heaterTimer.cancel();
			    heaterTimer= new Timer(); 
				heaterTimer.schedule(new HeaterControlTask(FirstHeatertoBoxID, heatTimes), heatTimes[HeaterTaskRunCount]*100);
				//执行步骤加一。
				 HeaterTaskRunCount++;
  			}
			else if(HeaterTaskRunCount==5){
				//最后一个加热器关闭
	  	  		  staticlocksState[PCBID][HeaterTaskRunCount-1]=(byte)0x00;
	  	  			byte[][] onBytes=CommonFunction.generateOpenRelayBytes(boxID,staticlocksState[PCBID]);
	  	  			serialPortOpt.writeBytes(onBytes[0]);
				heaterTimer.cancel(); 
			  System.out.println("---------heatControl complish--------");
			}
		
			
		}
		
		
		
	}
	
	private void heaterControl(int[] heatTimes){
	//	 byte PCBID= (byte)(FirstHeatertoBoxID/8+1);
	//	staticlocksState[PCBID][0]=(byte)0x01;
	////	byte[][] onBytes=generateOpenRelayBytes(FirstHeatertoBoxID);
	//		serialPortOpt.writeBytes(onBytes[0]);
		HeaterTaskRunCount=0;
		 heaterTimer= new Timer();
		 HeaterControlTask task= new HeaterControlTask(FirstHeatertoBoxID, heatTimes);		 			
		 heaterTimer.schedule(task, 0);
		

		
	}
	
	List<Integer> parseBoxes(String boxesIn) {
		List<Integer> boxes= new ArrayList<Integer>();
		for(int i=1;i*3<boxesIn.length();i++){
			String boxStr= boxesIn.substring((i-1)*3,i*3);
			boxes.add(Integer.parseInt(boxStr));
		}		
		return boxes;
	}	
	 

}
